#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "http-route.h"
#include "http-server-internal.h"
#include "urlcodec.h"

typedef struct {
	char *path;
	http_server_handler handler;
} http_route_t;

typedef struct {
	http_route_t *handlers;
	int handler_nums;
} http_server_route_t;

static http_server_route_t* http_server_get_route()
{
	static http_server_route_t router = {NULL, 0};
	return &router;
}

int http_server_addroute(const char* path, http_server_handler handler)
{
	http_server_route_t* router = http_server_get_route();
	router->handlers = (http_route_t *)realloc(router->handlers, (router->handler_nums + 1) * sizeof(http_route_t));
	assert(router->handlers);
	router->handlers[router->handler_nums].path = strdup(path);
	assert(router->handlers[router->handler_nums].path);
	router->handlers[router->handler_nums].handler = handler;
	router->handler_nums ++;
	return 0;
}

int http_server_delroute(const char* path)
{
	int i = 0;
	http_server_route_t* router = http_server_get_route();
	assert(router->handlers);
	for (; i < router->handler_nums; i++) {
		if (0 == strncmp(router->handlers[i].path, path, strlen(router->handlers[i].path))) {
			free(router->handlers[i].path);
			router->handler_nums--;
			memmove(&router->handlers[i], &router->handlers[i + 1], (router->handler_nums - i) * sizeof(http_route_t));
			return 0;
		}
	}

	return -1; // not found
}

int http_server_route(void* http, http_session_t* session, const char* method, const char* path)
{
	char reqpath[1024];//[PATH_MAX];
	//struct uri_t* uri = uri_parse(path, (int)strlen(path));
	url_decode(path, -1, reqpath, sizeof(reqpath));
	//uri_free(uri);

	//UTF8Decode utf8(reqpath);
	// TODO: path resolve to fix /rootpath/../pathtosystem -> /pathtosystem
	//path_resolve(buffer, sizeof(buffer), utf8, CWD, strlen(CWD));
	//path_realpath(buffer, live->path);

	int i = 0;
	http_server_route_t* router = http_server_get_route();
	assert(router->handlers);
	for (; i < router->handler_nums; i++) {
		if (0 == strncmp(router->handlers[i].path, reqpath, strlen(router->handlers[i].path))) {
			return router->handlers[i].handler(http, session, method, reqpath);
		}
	}

	http_server_set_status_code(session, 404, NULL);
	return http_server_send(session, "", 0, NULL, NULL);
}
